/******************************************************************************
 *      Mestrado em Ciência da Computação - UFMS
 *		Redes de Computadores - Prof. Dr. Ronaldo Alves Ferreira
 *		Alunos: Geraldo Landre, Marcel Tolentino, Vinícius Bueno
 *****************************************************************************/

#include "request.h"
#include "enums.h"

header_data * new_header()
{
    int i;
    header_data *hd = (header_data *) malloc(sizeof(header_data));
    hd->header = (vstring **) malloc(48 * sizeof(vstring *));
    hd->alive = 1;

    for(i = 0; i < 48; i++)
        hd->header[i] = NULL;

    hd->content_length = 0;
    hd->end = 0;
    hd->error = 0;
    hd->method = 0;
    hd->path = NULL;
    hd->file = NULL;
    hd->host = NULL;
    hd->http = NULL;
    hd->method_str = NULL;
    hd->msg = NULL;
    hd->port = NULL;
    hd->request = NULL;

    return hd;
}

void reset_header(header_data **hd)
{
    int i;
    
    (*hd)->alive = 1;
    (*hd)->content_length = 0;
    (*hd)->end = 0;
    (*hd)->error = 0;
    (*hd)->method = 0;

    free_string(&((*hd)->host));
    free_string(&((*hd)->http));
    free_string(&((*hd)->method_str));
    free_string(&((*hd)->msg));
    free_string(&((*hd)->port));
    free_string(&((*hd)->request));
    free_string(&((*hd)->path));
    free_string(&((*hd)->file));


    for(i = 0; i < 48; i++)
        free_string(&((*hd)->header[i]));
}

void copy_header_data(header_data **oldhd,header_data **newhd)
{
    (*newhd)->alive = (*oldhd)->alive;

    (*newhd)->content_length = (*oldhd)->content_length;
    (*newhd)->end = (*oldhd)->end;
    (*newhd)->error = (*oldhd)->error;
    (*newhd)->method = (*oldhd)->method;
    copy_vstring(&((*newhd)->host),(*oldhd)->host);
    copy_vstring(&((*newhd)->http),(*oldhd)->http);
    copy_vstring(&((*newhd)->method_str),(*oldhd)->method_str);
    copy_vstring(&((*newhd)->port),(*oldhd)->port);
    copy_vstring(&((*newhd)->request),(*oldhd)->request);
}


void print_header_data(const header_data *hd)
{
    int i;
    printf("_________________CONTEÚDO HEADER_DATA________________________\n");
    if(hd->msg != NULL)
        printf("msg_length: %i\n",hd->msg->length);
    printf("end: %i\n",hd->end);
    printf("error: %i\n",hd->error);
    printf("Alive: %i\n",hd->alive);

    if(hd->content_length)
        printf("Content-Length: %i\n",hd->content_length);
    
    printf("Host: ");
    print_string(hd->host);
    printf("Http: ");
    print_string(hd->http);
    printf("Method: ");
    print_string(hd->method_str);
    printf("Port: ");
    print_string(hd->port);
    printf("Request: ");
    print_string(hd->request);
    printf("Msg:\n\n");
    print_string(hd->msg);
    for(i = 0; i < 48; i++)
        if(hd->header[i] != NULL)
            print_string(hd->header[i]);
    printf("___________________________________________________________\n\n");
}

char* get_str_httperror(int error)
{
    switch(error)
    {
        case MSG_OK:
            return "200 OK";
        case ERR_MOVED_PERMANENTLY:
            return "301 Moved Permanently";
        case ERR_FOUND:
            return "302 Found";
        case ERR_BAD_REQUEST:
            return "400 Bad Request";
        case ERR_FORBIDDEN:
            return "403 Forbidden";
        case ERR_NOT_FOUND:
            return "404 Not Found";
        case ERR_LENGTH_REQUIRED:
            return "411 Length Required";
        case ERR_REQUEST_URI_TOO_LONG:
            return "414 Request-URI Too Long";
        case ERR_INTERNAL_SERVER_ERROR:
            return "500 Internal Server Error";
        case ERR_NOT_IMPLEMENTED:
            return "501 Not Implemented";
        case ERR_SERVICE_UNAVAILABLE:
            return "503 Service Unavailable";
        case ERR_HTTP_VERSION_NOT_SUPPORTED:
            return "505 HTTP Version Not Supported";

        /* TODO	INSERIR AS MENSAGENS DE ERRO AQUI	*/

        default:
            return NULL;
    }
}

int is_finished(header_data *hd)
{
    return hd->end;//(get_index_occour(hd->msg,END_HEADER) >= 0);
}